package com.joy.web.admin.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.joy.common.model.vo.RoleVO;
import com.joy.web.admin.mapper.RoleMapper;
import com.joy.web.admin.service.IRoleResourceService;
import com.joy.web.admin.service.IRoleService;
import com.joy.common.constant.CommonCons;
import com.joy.web.admin.entity.Role;
import com.joy.web.admin.entity.RoleResource;
import com.joy.web.base.service.impl.IBaseServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yjzhao
 * @since 2019-09-16
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class RoleServiceImpl extends IBaseServiceImpl<RoleMapper, Role> implements IRoleService {

    @Resource
    IRoleResourceService roleResourceService;

    @Override
    public List<Role> findAllRoleList() throws Exception {
        QueryWrapper<Role> qWrapper = new QueryWrapper<>();
        qWrapper.lambda().eq(Role::getDelYn, CommonCons.FlagType.N);
        return this.list(qWrapper);
    }

    @Override
    public IPage<Role> findRoleListPage(Page<Role> page, RoleVO roleVO) throws Exception {
        QueryWrapper<Role> qWrapper = new QueryWrapper<>();
        qWrapper.lambda().eq(Role::getDelYn, CommonCons.FlagType.N)
                .like(roleVO != null && StrUtil.isNotEmpty(roleVO.getRoleKey()),
                        Role::getRoleKey, roleVO.getRoleKey());
        return this.page(page, qWrapper);
    }

    @Override
    @Transactional(readOnly = false)
    @Caching(evict = {
            @CacheEvict(value= CommonCons.MyCache.PERMISSIONS,allEntries=true),
            @CacheEvict(value= CommonCons.MyCache.MENUTREE, allEntries = true)
    })
    public boolean updateRole(RoleVO roleVO) throws Exception {
        Role role = roleVO.convert(Role.class);
        boolean updateFlag = this.lambdaUpdate()
                .set(Role::getDescription, role.getDescription())
                .set(StrUtil.isNotEmpty(role.getRoleKey()),
                        Role::getRoleKey, role.getRoleKey())
                .set(StrUtil.isNotEmpty(role.getRoleName()),
                        Role::getRoleName, role.getRoleName())
                .eq(Role::getId, role.getId())
                .eq(Role::getDelYn, CommonCons.FlagType.N)
                .update();
        //更新权限
        //1. 删除原来权限
        roleResourceService.lambdaUpdate().set(RoleResource::getDelYn, CommonCons.FlagType.Y)
                .eq(RoleResource::getDelYn, CommonCons.FlagType.N)
                .eq(RoleResource::getRoleId, role.getId())
                .update();
        //2. insert 新权限
        List<Integer> resourceIdList = roleVO.getResourceIdList();
        saveRoleResource(role.getId(), resourceIdList);
        return updateFlag;
    }

    @Transactional(readOnly = false)
    @Override
    public boolean save(RoleVO roleVO) {
        Role role = roleVO.convert(Role.class);
        role.setId(IdUtil.simpleUUID());
        boolean saveFlag = this.retBool(baseMapper.insert(role));

        //新增权限
        List<Integer> resourceIdList = roleVO.getResourceIdList();
        saveRoleResource(role.getId(), resourceIdList);
        return saveFlag;
    }

    /**
     * @Description 保存角色权限对应关系
     * @param resourceIdList
     * @return
     * @Author yjzhao
     * @Date 2019/9/17 10:09
     **/
    private void saveRoleResource(String roleId, List<Integer> resourceIdList) {
        if (!CollectionUtils.isEmpty(resourceIdList)) {
            resourceIdList.forEach(resourceId -> {
                RoleResource roleResource = new RoleResource();
                roleResource.setRoleId(roleId);
                roleResource.setResourceId(resourceId);
                roleResourceService.save(roleResource);
            });
        }
    }

}
